<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
<title>Lynx6Arm Service Sample</title>
<style type="text/css">
 /* Font Definitions */
 @font-face
	{font-family:Verdana;}
 /* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
	{margin:0in;
	margin-bottom:.0001pt;
	font-size:12.0pt;
	font-family:Verdana, Arial, sans-serif;}
h1
	{margin-right:0in;
	margin-left:0in;
	font-size:24.0pt;
	font-family:Verdana, Arial, sans-serif;
	font-weight:bold;}
h2
	{margin-right:0in;
	margin-left:0in;
	font-size:18.0pt;
	font-family:Verdana, Arial, sans-serif;
	font-weight:bold;}
p.MsoPlainText, li.MsoPlainText, div.MsoPlainText
	{margin-right:0in;
	margin-left:0in;
	font-size:12.0pt;
	font-family:Verdana, Arial, sans-serif;}
p
	{margin-right:0in;
	margin-left:0in;
	font-size:12.0pt;
	font-family:Verdana, Arial, sans-serif;}
pre
	{margin-top:0in;
	margin-right:30.6pt;
	margin-bottom:0in;
	margin-left:30.6pt;
	margin-bottom:.0001pt;
	background:#D6D6A0;
	font-size:11.0pt;
	font-family:"Courier New";}
span.sdk
	{font-style:italic;}
@page Section1
	{size:8.5in 11.0in;
	margin:1.0in 1.25in 1.0in 1.25in;}
div.Section1
	{page:Section1;}

.TCH { font-family: Arial Black; font-size: 12pt; background-color: #b3b3b3; }
.TX { font-family: Arial; font-size: 12pt; background-color: #e6e6e6; }
</style>

</head>

<body><a name="top" />

<div class="Section1">

<h1><span style='font-family:Verdana'>Lynx6Arm Service Sample</span></h1>

<p><i><span style='font-size:11.0pt;font-family:Verdana'>This file is part of
the Microsoft Robotics Studio Code Samples. Copyright &copy; Microsoft
Corporation. All rights reserved.<br />
Updated Nov-2007 by Trevor Taylor, Software Technology, Australia</span></i></p>

<p class="MsoNormal"><span style='font-family:Verdana'>The Lynx6Arm service is a Decentralized System Service (DSS)
that connects to a Lynxmotion Lynx 6 Robotic Arm via a Lynxmotion SSC-32 Servo
Controller over a serial port connection. The service has a service partner,
the <a href="SSC32.htm">SSC32 service</a>, that sends commands to
the servo controller. The Lynx6Arm service implements
the generic ArticulatedArm contract in RoboticsCommon as an alternate contract.</span></p>

<h2><span style='font-family:Verdana'>Hardware and Software Prerequisites</span></h2>

<p class="MsoPlainText" style='margin-left:.5in;text-indent:-.25in'><span
style='font-size:10.0pt;font-family:Symbol'>&middot;</span><span
style='font-size:7.0pt'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span
style='font-family:Verdana'>A Lynxmotion Lynx 6 Robotic Arm.</span></p>

<p class="MsoPlainText" style='margin-left:.5in;text-indent:-.25in'><span
style='font-size:10.0pt;font-family:Symbol'>&middot;</span><span
style='font-size:7.0pt'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span
style='font-family:Verdana'>A Lynxmotion SSC-32 Servo Controller with the
SSC-32 Firmware loaded.</span></p>

<p class="MsoPlainText" style='margin-left:.5in;text-indent:-.25in'><span
style='font-size:10.0pt;font-family:Symbol'>&middot;</span><span
style='font-size:7.0pt'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span
style='font-family:Verdana'>A serial port (currently COM1 -- you must edit and recompile the service to change this).</span></p>

<p class="MsoPlainText"><span style='font-family:Verdana'>Note: The Lynx6Arm service
assumes that the robotic arm is connected to the controller as described below,
<b>not</b> in the manner described by the Lynxmotion Assembly Guide.
In particular, the servos are connected as in the table below:</span></p>

<table>
<tr class="TCH">
    <td>SSC-32 Servo Number</td>
    <td>Arm Servo Function</td>
</tr>
<tr class="TX">
    <td>0</td>
    <td>Base Rotate</td>
</tr>
<tr class="TX">
    <td>1</td>
    <td>Shoulder</td>
</tr>
<tr class="TX">
    <td>2</td>
    <td>Elbow</td>
</tr>
<tr class="TX">
    <td>3</td>
    <td>Wrist</td>
</tr>
<tr class="TX">
    <td>4</td>
    <td>Wrist Rotate*</td>
</tr>
<tr class="TX">
    <td>5</td>
    <td>Gripper*</td>
</tr>
</table>
<p>
* These two are reversed compared to the Lynxmotion documentation.
It does no harm if you get them wrong, but they will not work as
expected.</p>

<a href="#top"><img src="images/top.gif" border="0" alt="Top of Page" /></a>
<a href="#top" title="Top of Page">Top of Page</a>

<h2><span style='font-family:Verdana'>To Start and Run the Sample</span></h2>

<p><span style='font-family:Verdana'>Start the <em><span style='font-family:
Verdana'>Microsoft Robotics Studio Command Prompt</span></em> from the Programs menu.</span></p>

<p><span style='font-family:Verdana'>Connect the robotic arm to the controller
and plug the servo controller into the serial port.</span></p>

<p><span style='font-family:Verdana'>Start a DssHost node and create an
instance of the service by typing the following command:</span></p>

<pre>dsshost /p:50000 /m:"ProMRDS/Config/Lynxmotion.Lynx6Arm.manifest.xml"</pre>

<p><span style='font-family:Verdana'>This will start the service and you get a
response like this:</span></p>

<pre>Initializing Dss Node with manifest file: .../ProMRDS/Config/Lynxmotion.Lynx6Arm.manifest.xml </pre>

<p><span style='font-family:Verdana'>
If you prefer, you can use a command procedure that starts
both the arm and a simple Dashboard. The Dashboard has the
ability to change the angle of one joint at a time, so you
can use it to test the Lynx6Arm service. To run the command
procedure, at the MRDS command prompt type:</span>
</p>
<pre>RunLynx6Arm</pre>

<p><span style='font-family:Verdana'>Please note: At start up, the service
automatically sends a positioning command to the arm, initializing all the
servos on the arm to an angle of 0 degrees. The movements may be sudden and the
arm will probably jerk. It helps if the arm is roughly in the startup
position when you turn the power off so that it does not have far to
go the next time you want to use it. </span></p>

<a href="#top"><img src="images/top.gif" border="0" alt="Top of Page" /></a>
<a href="#top" title="Top of Page">Top of Page</a>

<h2><span style='font-family:Verdana'>To Inspect the Service</span></h2>

<p><span style='font-family:Verdana'>Start Internet Explorer (IE) and type the
&quot;Service uri&quot; specified in your command prompt.&nbsp; For example:</span></p>

<pre>http://localhost:50000/lynx6arm</pre>

<p><span style='font-family:Verdana'>This will display the Lynx6Arm service
running on your node.&nbsp;You will be able to see the current state of the 5
joints and gripper of the arm.</span></p>

<a href="#top"><img src="images/top.gif" border="0" alt="Top of Page" /></a>
<a href="#top" title="Top of Page">Top of Page</a>

<h2><span style='font-family:Verdana'>Lynx 6 Arm Configuration</span></h2>

<p><span style='font-family:Verdana'>The Lynx6Arm service represents the
physical robotic arm as a list of joints, implementing the contract defined in
ArticulatedArmState. The 5 joints of the arm are defined in a serial order from
the base to the wrist rotate. Each joint has only one degree of
&#8220;twist&#8221; angular freedom and a range from -90 degrees to 90 degrees
about the joint axis. The joint axis and joint normal are designated using the
left-hand coordinate system. If you would like more details about describing
the properties of a joint, you should review Simulation Tutorial 4.</span></p>

<p><span style='font-family:Verdana'>Below we provide a graphical
representation of the Lynx6ArmConfiguration used in the service. Note that
the Lynx6ArmIK service (Inverse Kinematics) that originally shipped with
the software has been removed. Instead the calculations are done inside
the Lynx6Arm service itself.
<!-- Please refer
to the Lynx6ArmIK service about the selection of joint normal for each joint.-->
</span></p>

<p><img width=350 height=500 src="images/ArmAxes.gif"></p>

<a href="#top"><img src="images/top.gif" border="0" alt="Top of Page" /></a>
<a href="#top" title="Top of Page">Top of Page</a>

<h2><span style='font-family:Verdana'>Lynx 6 Arm Operations</span></h2>

<p><span style='font-family:Verdana'>The Lynx6Arm service supports all of 
the operations defined in the generic Articulated Arm service that shipped
with MSRS V1.5. This includes the <span style='font-size:11.0pt;font-family:"Courier New";
color:teal'>Get </span> operation to get the joint names
and angles, and the <span style='font-size:11.0pt;font-family:"Courier New";
color:teal'>SetJointTargetPose </span> operation to move a single joint. Joint angles
are specified in degrees. There are hard-coded limits on the joint angles to prevent
you from accidentally damaging the arm. Some joints therefore do not have the full
-90 to +90 degree travel when using this service.
</span></p>

<table>
<tr class="TCH">
    <td>Servo</td>
    <td>Zero Position</td>
    <td>Positive Direction (increasing angle)</td>
</tr>
<tr class="TX">
    <td>Base</td>
    <td>Facing away from SSC-32</td>
    <td>Clockwise (right)</td>
</tr>
<tr class="TX">
    <td>Shoulder</td>
    <td>Vertical</td>
    <td>Lean backwards</td>
</tr>
<tr class="TX">
    <td>Elbow</td>
    <td>Right angle to upper arm*</td>
    <td>Bend down</td>
</tr>
<tr class="TX">
    <td>Wrist</td>
    <td>In line with lower arm</td>
    <td>Bend up</td>
</tr>
<tr class="TX">
    <td>Wrist Rotate</td>
    <td>Horizontal</td>
    <td>Anti-clockwise (left)</td>
</tr>
</table>

<p>
* If you look carefully at the elbow, you will see that it is
connected to the lower arm with an offset of 20 degrees.
The service compensates for this so that an angle of zero
will be a right angle with the upper arm.</p>

<p><span style='font-family:Verdana'>The following two operations work in a world
coordinate frame:
</span><span style='font-size:11.0pt;font-family:"Courier New";
color:teal'>GetEndEffectorPose </span><span style='font-family:Verdana'>and </span><span
style='font-size:11.0pt;font-family:"Courier New";color:teal'>SetEndEffectorPose</span><span
style='font-family:Verdana'>.</span></p>

<!--
Both operations depend on the Lynx6ArmIK service
to solve the mathematics equations of the arm. At the start of the Lynx6Arm
service, the service sends a Replace message to its Lynx6ArmIk partner,
initializing the Lynx6ArmIK service with the configuration of the arm.
-->

<p><span style='font-family:Verdana'><b>IMPORTANT NOTE:</b>
The coordinate frame used by this service does not conform to the Lynxmotion
standard. As long as you use coordinates from <span style='font-size:11.0pt;font-family:"Courier New";
color:teal'>GetEndEffectorPose </span>as input to <span
style='font-size:11.0pt;font-family:"Courier New";color:teal'>SetEndEffectorPose</span>
this does not matter. The coordinate system is shown in the figure below and is
defined as follows:<br />
Sit at the left-hand side of the Lynx 6 arm facing the switch and serial port plug.<br />
The origin is at the center of the base at gound level.<br />
The X Axis runs from left to right.<br />
The Y Axis runs upwards.<br />
The Z Axis comes out towards you.<br />
<b>In this coordinate frame, the X coordinate values will always be negative!</b>
</span></p>
<p>
<img src="images/Lynx6Coords.jpg" width="560" height="400" alt="Lynx 6 Coordinate System" />
</p>

<p><span style='font-family:Verdana'>The </span><span style='font-size:11.0pt;
font-family:"Courier New";color:teal'>GetEndEffectorPose </span><span
style='font-family:Verdana'>operation will return the current Pose (orientation
and position) of the end effector. The end effector pose originated at the base
of the gripper and is described using a right-handed base coordinate frame.
Through the </span><span style='font-size:11.0pt;font-family:"Courier New";
color:teal'>SetEndEffectorPose </span><span style='font-family:Verdana'>operation,
you can specify a Pose (in the right-handed base coordinate frame) for the end
effector and the service will move the arm to the desired pose. For more
information on the inverse kinematics, please read the code.</span></p>

<a href="#top"><img src="images/top.gif" border="0" alt="Top of Page" /></a>
<a href="#top" title="Top of Page">Top of Page</a>

<hr />

</div>

</body>

</html>
